package com.rightsidetech.mall.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.rightsidetech.mall.dto.request.SpecsPageReq;
import com.rightsidetech.mall.dto.request.SpecsReq;
import com.rightsidetech.mall.dto.request.SpecsUpReq;
import com.rightsidetech.mall.dto.request.SpecsUpValueReq;
import com.rightsidetech.mall.dto.response.SpecsPageResp;
import com.rightsidetech.mall.entity.MallSpecs;
import com.rightsidetech.mall.mapper.MallSpecsMapper;
import com.rightsidetech.mall.service.MallSpecsService;
import com.rightsidetech.commom.base.DelReq;
import com.rightsidetech.commom.base.ResponseData;
import com.rightsidetech.commom.enums.CodeIdEnum;
import com.rightsidetech.commom.utils.BeanValidator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;

import javax.annotation.Resource;
import javax.validation.ConstraintViolation;
import java.util.*;
import java.util.stream.Collectors;

@Service("mallSpecsService")
public class MallSpecsServiceImpl implements MallSpecsService {

    @Resource
    private MallSpecsMapper mallSpecsMapper;

    @Autowired
    private DataSourceTransactionManager dataSourceTransactionManager;
    @Autowired
    private TransactionDefinition transactionDefinition;

    @Override
    public ResponseData saveSpecs(SpecsReq req, String createName, Long createId) {
        ConstraintViolation validate = BeanValidator.validate(req);
        if (validate != null) {
            return new ResponseData<>(CodeIdEnum.ParameterMalformed.getValue(), validate.getMessage());
        }
        List<String> values = req.getSpecsValue();
        boolean flag = CollUtil.isNotEmpty(values);
        if (flag) {
            if (new HashSet<>(values).size() < values.size()) {
                return ResponseData.fail(CodeIdEnum.ParameterMalformed.getValue(), "规格值不可重复");
            }
        }
        Long count = mallSpecsMapper.selectCountBySpecsName(req.getSpecsName());
        if (count > 0) {
            return ResponseData.fail(CodeIdEnum.ParameterMalformed.getValue(), "已存在相同的规格名");
        }
        TransactionStatus transaction = dataSourceTransactionManager.getTransaction(transactionDefinition);
        try {
            String name = req.getSpecsName();
            Date date = new Date();
            MallSpecs specs = new MallSpecs();
            specs.setCreatedAt(date);
            specs.setCreaterId(createId);
            specs.setCreaterName(createName);
            specs.setIsDeleted((byte) 0);
            specs.setParentId(0L);
            specs.setSpecs(name);
            if (mallSpecsMapper.insertSelective(specs) <= 0) {
                dataSourceTransactionManager.rollback(transaction);
                return ResponseData.fail("新增失败");
            }
            if (!flag) {
                dataSourceTransactionManager.commit(transaction);
                return ResponseData.success(CodeIdEnum.Success);
            }
            int sort = 1;
            Long id = specs.getId();
            specs.setParentId(id);
            for (String value : values) {
                specs.setId(null);
                specs.setSpecs(value);
                specs.setSpecsOrder(sort);
                if (mallSpecsMapper.insertSelective(specs) <= 0) {
                    dataSourceTransactionManager.rollback(transaction);
                    return ResponseData.fail("新增失败");
                }
                sort++;
            }
        } catch (Exception e) {
            e.printStackTrace();
            dataSourceTransactionManager.rollback(transaction);
            return ResponseData.fail("新增失败");
        }
        dataSourceTransactionManager.commit(transaction);
        return ResponseData.success(CodeIdEnum.Success);
    }

    @Override
    public ResponseData updateSpecs(SpecsUpReq req, String updaterName, Long updaterId) {
        ConstraintViolation validate = BeanValidator.validate(req);
        if (validate != null) {
            return new ResponseData<>(CodeIdEnum.ParameterMalformed.getValue(), validate.getMessage());
        }
        List<SpecsUpValueReq> valueList = req.getValueList();
        if (CollUtil.isNotEmpty(valueList)) {
            List<Long> idsIsNull = valueList.stream().map(SpecsUpValueReq::getId).collect(Collectors.toList());
            List<Long> ids = idsIsNull.stream().filter(id -> ObjectUtil.isNotEmpty(id)).collect(Collectors.toList());
            if(CollUtil.isNotEmpty(ids)){
                Integer count = mallSpecsMapper.selectCountByIds(ids);
                if(count != ids.size()){
                    return ResponseData.fail("存在非法id");
                }
            }
            Set<String> collect = valueList.stream().map(SpecsUpValueReq::getSpecsValue).collect(Collectors.toSet());
            if (collect.size() < valueList.size()) {
                return ResponseData.fail(CodeIdEnum.ParameterMalformed.getValue(), "规格值不可重复");
            }
            for (SpecsUpValueReq valueReq : valueList) {
                ConstraintViolation date = BeanValidator.validate(valueReq);
                if (date != null) {
                    return new ResponseData<>(CodeIdEnum.ParameterMalformed.getValue(), date.getMessage());
                }
            }
        }
        MallSpecs specs = mallSpecsMapper.selectByPrimaryKey(req.getId());
        if (ObjectUtil.isEmpty(specs) || specs.getIsDeleted() == 1) {
            return ResponseData.fail(CodeIdEnum.ParameterMalformed.getValue(), "规格不存在");
        }
        if (!specs.getSpecs().equals(req.getSpecsName())) {
            Long count = mallSpecsMapper.selectCountBySpecsName(req.getSpecsName());
            if (count > 0) {
                return ResponseData.fail(CodeIdEnum.ParameterMalformed.getValue(), "已存在相同的规格名");
            }
        }
        MallSpecs specsName = new MallSpecs();
        specsName.setId(specs.getId());
        specsName.setIsDeleted((byte) 0);
        specsName.setParentId(0L);
        specsName.setUpdaterId(updaterId);
        specsName.setUpdaterName(updaterName);
        specsName.setSpecs(req.getSpecsName());
        if (mallSpecsMapper.updateByPrimaryKeySelective(specsName) <= 0) {
            return ResponseData.fail("操作失败");
        }
        if (CollUtil.isNotEmpty(valueList)) {
            List<MallSpecs> specsList = mallSpecsMapper.selectListByParentId(req.getId());
            if(CollUtil.isNotEmpty(specsList)){
                List<Long> vIds = valueList.stream().filter(value -> value.getId() != null).map(SpecsUpValueReq::getId).collect(Collectors.toList());
                if(CollUtil.isNotEmpty(vIds)){
                    for (Long id : vIds) {
                        specsList = specsList.stream().filter(sp -> !sp.getId().equals(id)).collect(Collectors.toList());
                    }
                }
                List<Long> ids = specsList.stream().map(MallSpecs::getId).collect(Collectors.toList());
                if(CollUtil.isNotEmpty(ids)){
                    mallSpecsMapper.isDeleteByIds(ids);
                }
            }
            int i = 0;
            for (SpecsUpValueReq value : valueList) {
                if (value.getId() != null){
                    MallSpecs specsValue = new MallSpecs();
                    specsValue.setId(value.getId());
                    specsValue.setSpecs(value.getSpecsValue());
                    specsValue.setUpdatedAt(new Date());
                    specsValue.setUpdaterId(updaterId);
                    specsValue.setUpdaterName(updaterName);
                    specsValue.setSpecsOrder(i);
                    mallSpecsMapper.updateByPrimaryKeySelective(specsValue);
                }else {
                    MallSpecs specsValue = new MallSpecs();
                    specsValue.setCreatedAt(new Date());
                    specsValue.setCreaterId(updaterId);
                    specsValue.setCreaterName(updaterName);
                    specsValue.setIsDeleted((byte) 0);
                    specsValue.setParentId(specsName.getId());
                    specsValue.setSpecs(value.getSpecsValue());
                    specsValue.setSpecsOrder(i);
                    mallSpecsMapper.insertSelective(specsValue);
                }
                i++;
            }
        }else {
            List<MallSpecs> specsList = mallSpecsMapper.selectListByParentId(req.getId());
            if(CollUtil.isNotEmpty(specsList)){
                List<Long> ids = specsList.stream().map(MallSpecs::getId).collect(Collectors.toList());
                mallSpecsMapper.isDeleteByIds(ids);
            }
        }
        return ResponseData.success(CodeIdEnum.Success);
    }

    @Override
    public ResponseData isDelete(DelReq req) {
        ConstraintViolation validate = BeanValidator.validate(req);
        if (validate != null) {
            return new ResponseData<>(CodeIdEnum.ParameterMalformed.getValue(), validate.getMessage());
        }
        MallSpecs specs = mallSpecsMapper.selectByPrimaryKey(req.getId());
        if (ObjectUtil.isEmpty(specs) || specs.getIsDeleted() == 1) {
            return ResponseData.fail(CodeIdEnum.ParameterMalformed.getValue(), "删除的数据不存在");
        }
        if (specs.getParentId() == 0L) {
            Long count = mallSpecsMapper.selectCountByParentId(specs.getId());
            if (count > 0) {
                return ResponseData.fail(CodeIdEnum.ParameterMalformed.getValue(), "此规格名还有规格值不允许删除");
            }
        }
        MallSpecs record = new MallSpecs();
        record.setId(req.getId());
        record.setIsDeleted((byte) 1);
        if (mallSpecsMapper.updateByPrimaryKeySelective(record) <= 0) {
            return ResponseData.fail("删除失败");
        }
        return ResponseData.success(CodeIdEnum.Success);
    }

    @Override
    public ResponseData<PageInfo<SpecsPageResp>> page(SpecsPageReq req) {
        ConstraintViolation validate = BeanValidator.validate(req);
        if (validate != null) {
            return new ResponseData<>(CodeIdEnum.ParameterMalformed.getValue(), validate.getMessage());
        }
        PageHelper.startPage(req.getPageNo(), req.getPageSize());
        List<SpecsPageResp> result = mallSpecsMapper.selectPageList(req);
        for (SpecsPageResp resp : result) {
            if (null == resp.getCount() || resp.getCount() <= 0) {
                resp.setChildren(null);
                resp.set_loading(null);
            }
        }
        return ResponseData.success(new PageInfo<>(result));
    }

    @Override
    public ResponseData<List<SpecsPageResp>> getSpecsValue(Long id) {
        if (null == id || id <= 0) {
            return ResponseData.fail(CodeIdEnum.ParameterMalformed.getValue(), "id不可为空,不可小于0");
        }
        List<SpecsPageResp> list = mallSpecsMapper.selectValueList(id);
        for (SpecsPageResp resp : list) {
            resp.set_loading(null);
            resp.setChildren(null);
        }
        return ResponseData.success(list);
    }

    @Override
    public ResponseData<List<SpecsPageResp>> getAll() {
        return ResponseData.success(mallSpecsMapper.selectAll());
    }

}
